package com.dl.mall.listener;

import com.dl.mall.config.RabbitmqConfig;
import com.dl.mall.entity.user.Order;
import com.dl.mall.entity.user.OrderInfo;
import com.dl.mall.exception.NoInventoryException;
import com.dl.mall.mapper.OrderMapper;
import com.dl.mall.utils.RedisUtils;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * rabbitmq订单消费者
 * implements ChannelAwareMessageListener
 * @author DL
 * @create 2022-05-07 17:22
 */
@Slf4j
@Component
public class OrderConsumer {

    @Resource
    private OrderMapper orderMapper;
    @Resource
    private RedisUtils redisUtils;

    @RabbitListener(queues = RabbitmqConfig.QUEUE_A)
    public void receiveQueueA(Map<String, Object> map,Message message, Channel channel) throws IOException {
        Order order = (Order) map.get("order");
        System.out.println("order = " + order);
        List<OrderInfo> orderInfoList = (List<OrderInfo>) map.get("orderInfoList");
        try {
            log.info("完成：当前时间：{}，收到队列 QUEUE_A 的信息：{}", new Date().toString(), map);
            int insertOrder = orderMapper.insertOrder(order);// 向订单表插入
            int insertOrderInfo = orderMapper.insertOrderInfo(orderInfoList);// 向订单信息表插入
            if (insertOrder != 0 && insertOrderInfo != 0){// 必须都成功
                // 确认收到消息，false只确认当前consumer一个消息收到，true确认所有consumer获得的消息
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                log.info("QUEUE_A的 {} 消息已重复处理失败，拒绝再次接收，进入死信队列", order);
                // 拒绝消息，requeue=false 表示不再重新入队，如果配置了死信队列则进入死信队列
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                log.info("尝试将QUEUE_A的 {} 消息再次返回队列处理", order);
                // requeue为是否重新回到队列，true重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }

}
